#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys,re,math
import time
import operator
from datetime import date
from sheepomatic_io import Csv_file,Shepherd_brief_file
from sheepomatic import Sheep,Shepherd
import sheepomatic

class Norm_shepherd:
   @classmethod
   def norm_shepherd(cls,shepherd_filename,conf_filename):
      shepherd_list = Csv_file.read_and_interpret_shepherd_file(shepherd_filename,conf_filename)
      # PERFORM INTEGRITY CHECKS
      # check mail address uniqueness
      mail_set = set([])       # set of mail addresses
      dupl_mail_set = set([])  # set of duplicate mail addresses
      for shepherd in shepherd_list:
         if shepherd.mail in mail_set:
            dupl_mail_set.add(shepherd.mail)
         else:
            mail_set.add(shepherd.mail)
      if len(dupl_mail_set):
         print >> sys.stderr, "Duplicate mail addresses:"
         for mail in dupl_mail_set:
            print >> sys.stderr, mail
         sys.exit(1)
      # PRINT RAW STATS
      cls.shepherd_stats(shepherd_list)
      # NORMALIZE
      undef_value = "unknown"
      undef_values = set(["unknown",""," "])
      norm_cs_country = sheepomatic.normfile2hash("conv/czech2iso3166-1.txt")
      norm_cs_lang = sheepomatic.normfile2hash("conv/czech2iso639-1.txt")
      norm_cs_gender = sheepomatic.normfile2hash("conv/cs2gender.txt")
      for shepherd in shepherd_list:
         # langs (norm - fail if can't)
         shepherd.langs = map(lambda lang: sheepomatic.normalize(norm_cs_lang, lang), shepherd.langs)
         # country (norm - fail if can't)
         # ... + take only first 3 preferences
         if len(shepherd.country_prefs) > 3:
            del shepherd.country_prefs[3:]
         shepherd.country_prefs = map(lambda country: sheepomatic.normalize(norm_cs_country, country), shepherd.country_prefs)
         # dates (already normed)
         # faculty (already normed)
         # gender (norm - fail if can't)
         shepherd.gender = sheepomatic.normalize(norm_cs_gender,shepherd.gender)
      return shepherd_list

   @classmethod
   def shepherd_stats(cls, shepherd_list):
      undef_values = set(["unknown",""," "])
      #   hashes
      norm_cs_country = sheepomatic.normfile2hash("conv/czech2iso3166-1.txt")
      #   country
      country_freq_hash = {}
      unknown_countries = set([])
      #   dates
      undef_date_shepherds = []
      date_freq_hash = {}
      #   faculty
      fac_freq_hash = {}
      # gender
      gender_freq_hash = {}
      for shepherd in shepherd_list:
         # country
         #if sheep.country not in country_freq_hash:
         #   country_freq_hash[sheep.country] = 0
         #country_freq_hash[sheep.country] += 1
         #if not sheep.country in norm_en_country:
         #   unknown_countries.add(sheep.country)
         # dates
         if shepherd.ava_date in undef_values:
            undef_date_shepherds.append(shepherd)
         else:
            if shepherd.ava_date not in date_freq_hash:
               date_freq_hash[shepherd.ava_date] = 0
            date_freq_hash[shepherd.ava_date] += 1
         # faculty
         if shepherd.faculty not in fac_freq_hash:
            fac_freq_hash[shepherd.faculty] = 0
         fac_freq_hash[shepherd.faculty] += 1
         # gender
         if shepherd.gender not in gender_freq_hash:
            gender_freq_hash[shepherd.gender] = 0
         gender_freq_hash[shepherd.gender] += 1
      # PRINT RAW STATS
      # countries
      #print >> sys.stderr, "ALL COUNTRIES:"
      #for country,country_freq in sorted(country_freq_hash.iteritems(),\
      #                                   key=operator.itemgetter(1), reverse=True):
      #   print >> sys.stderr, country+":",str(country_freq)
      #if len(unknown_countries) > 0:
      #   print >>sys.stderr, "UNKNOWN COUNTRIES:"
      #   for country in unknown_countries:
      #      print >> sys.stderr, country+":",str(country_freq_hash[country])
      #else:
      #   print >>sys.stderr, "NO UNKNOWN COUNTRIES"
      # dates
      print >> sys.stderr, "DEFINED DATES:"
      for d in sorted(date_freq_hash):
         print >> sys.stderr, d,": ",str(date_freq_hash[d])
      print >>sys.stderr, str(len(undef_date_shepherds)),"dates undefined."
      avg_date = cls.get_avg_date(date_freq_hash)
      print >>sys.stderr, "Avg. defined date is",avg_date
      # faculty
      print >> sys.stderr, "ALL FACULTIES:"
      for faculty,fac_freq in sorted(fac_freq_hash.iteritems(),\
                                     key=operator.itemgetter(1), reverse=True):
         print >> sys.stderr, faculty+":",str(fac_freq)
      # gender
      print >> sys.stderr, "GENDERS:"
      for gender,gender_freq in sorted(gender_freq_hash.iteritems(),\
                                       key=operator.itemgetter(1), reverse=True):
         print >> sys.stderr, gender+":",str(gender_freq)
      return

   @classmethod
   def get_avg_date(cls,date_freq_hash):
      aggregator = 0
      count = 0
      for d in date_freq_hash:
         aggregator += date_freq_hash[d]*d.toordinal()
         count += date_freq_hash[d]
      res_ordinal = int(math.floor(aggregator/count))
      return date.fromordinal(res_ordinal)

def main(args):
    # process parameters
    shepherd_filename = args[0]
    conf_filename = args[1]
    # read and norm sheep
    normed_shepherd_list = Norm_shepherd.norm_shepherd(shepherd_filename,conf_filename)
    # write the sheep to std. out
    Shepherd_brief_file.write_shepherd_brief_file(normed_shepherd_list)
    

if __name__ == '__main__':
    args = sys.argv[1:]
    main(args)
